/**
 * @Author: yzy
 * @Description:
 * @Version: 1.0.0
 * @Date: 2021/7/2 10:01
 * @Copyright: MIN-Group；国家重大科技基础设施——未来网络北大实验室；深圳市信息论与未来网络重点实验室
 */
package analysiscontroller

import (
	"context"
	"encoding/json"
	"vpn-management-server/logger"
	"vpn-management-server/network"
	"vpn-management-server/security/code"
	"vpn-management-server/src/dao/rgroupdao"
	"vpn-management-server/src/dao/ruledao"
	"vpn-management-server/src/dao/ugroupdao"
	"vpn-management-server/src/dao/userdao"
	"vpn-management-server/src/dao/whitelistdao"
	"vpn-management-server/src/model/analysismodel"
	"vpn-management-server/src/service/ugroupservice"
	"vpn-management-server/src/service/userlogservice"
)

// GetUGroupDataAnalysis 用户组内规则总数 规则组总数 用户总数 白名单总数 日志总数（两种） 日志产生频次（两种）
func GetUGroupDataAnalysis(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	if GetUGroupAnalysis, ok := request.GetModel().(*analysismodel.GetUGroupDataAnalysis); ok {
		resData := struct {
			RuleCount      int
			RGroupCount    int
			UserCount      int
			WhiteListCount int
			WarnCounts     []int
			NormalCounts   []int
		}{}
		// 某用户组的规则组数量
		resData.RGroupCount = rgroupdao.GetRGroupsCount(GetUGroupAnalysis.UGroupID)
		// 某用户组的规则数量
		resData.RuleCount = ruledao.GetUGroupRulesCount(GetUGroupAnalysis.UGroupID)
		// 某用户组的用户数量
		resData.UserCount = userdao.GetUserCountByUGroupID(GetUGroupAnalysis.UGroupID)
		// 某用户组的白名单数量
		resData.WhiteListCount = whitelistdao.GetWhiteListCountByUGroupID(GetUGroupAnalysis.UGroupID)
		// 1.告警 普通 2. 不分页 某个用户组 不分页的 所有  时间段
		//// 获取这个时间段的用户组日志
		//NLogs, _ := userlogservice.GetAllNormalLogsByUGroupIDAndTimestamp(getAllLogsByUGroupID)
		//WLogs, _ := userlogservice.GetAllWarningLogsByUGroupIDAndTimestamp(getAllLogsByUGroupID)
		//BeginTime, err := strconv.ParseInt(GetUGroupAnalysis.BeginTime, 10, 64)
		//if err != nil {
		//	logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "timestamp parse fail")
		//	response.Code = code.BAD_REQUEST
		//	response.ErrorMsg = "timestamp parse fail"
		//	return
		//}
		resData.WarnCounts = userlogservice.GetWarnLogsAnalysisByUGroupID(GetUGroupAnalysis)
		//logger.Logger.Debug("warn logger:", WLogs)
		//logger.Logger.Debug("warn logger count:", resData.WarnCounts)
		resData.NormalCounts = userlogservice.GetNormLogsAnalysisByUGroupID(GetUGroupAnalysis)
		//logger.Logger.Debug("normal logger:", NLogs)
		//logger.Logger.Debug("normal logger count:", resData.NormalCounts)
		data, _ := json.Marshal(resData)
		response.Code = code.SUCCESS
		response.Data = data
		logger.Logger.Info("get ugroup data analysis success")
	} else {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "Transform interface to GetUGroupDataAnalysis fail")
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "transform interface to GetUGroupDataAnalysis fail"
	}
}

func GetDataAnalysis(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {

	if getDataAnalysis, ok := request.GetModel().(*analysismodel.GetDataAnalysis); ok {
		resData := struct {
			RuleCount       int
			RGroupCount     int
			UserCount       int
			WhiteListCount  int
			WarnCounts      []int
			NormalCounts    []int
			UGroupUserCount map[string]int
		}{}
		// 规则组数量
		resData.RGroupCount = rgroupdao.GetRGroupsCount(-1)
		// 规则数量
		resData.RuleCount = ruledao.GetRulesCount()
		// 用户数量
		resData.UserCount = userdao.GetAllUserCount()
		// 白名单数量
		resData.WhiteListCount = whitelistdao.GetAllWhiteListCount()
		// 1.告警 普通 2. 不分页 某个用户组 不分页的 所有  时间段
		/*
			var getAllLogs = &userlogmodel.GetAllLogs{
				BeginTime: getDataAnalysis.BeginTime,
				EndTime:   getDataAnalysis.EndTime,
			}

			// 获取这个时间段的用户组日志
			NLogs, NCount := userlogservice.GetAllNormalLogsByTimestamp(getAllLogs)
			WLogs, WCount := userlogservice.GetAllWarningLogsByTimestamp(getAllLogs)
			if NCount == -1 || WCount == -1 {
				logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "connect to blockchain fail")
				response.Code = code.INTERNAL_SERVER_ERROR
				response.ErrorMsg = "connect to blockchain fail"
				return
			}
			BeginTime, err := strconv.ParseInt(getDataAnalysis.BeginTime, 10, 64)
			if err != nil {
				logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "timestamp parse fail")
				response.Code = code.BAD_REQUEST
				response.ErrorMsg = "timestamp parse fail"
				return
			}
			resData.WarnCounts = userlogservice.GetWarningLogsAnalysis(WLogs, getDataAnalysis.Num, BeginTime)
			//logger.Logger.Debug("warn logger:", WLogs)
			//logger.Logger.Debug("warn logger count:", resData.WarnCounts)
			resData.NormalCounts = userlogservice.GetNormalLogsAnalysis(NLogs, getDataAnalysis.Num, BeginTime)
			//logger.Logger.Debug("normal logger:", NLogs)
			//logger.Logger.Debug("normal logger count:", resData.NormalCounts)
		*/
		resData.WarnCounts = userlogservice.GetWarnLogsAnalysis(getDataAnalysis)
		resData.NormalCounts = userlogservice.GetNormLogsAnalysis(getDataAnalysis)
		resData.UGroupUserCount = ugroupservice.GetAllUGroupUserCountService()
		logger.Logger.Debug("UGroup user count:", resData.UGroupUserCount)
		data, _ := json.Marshal(resData)
		response.Code = code.SUCCESS
		response.Data = data
		logger.Logger.Info("get data analysis success")
	} else {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "Transform interface to GetDataAnalysis fail")
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "transform interface to GetDataAnalysis fail"
	}
}

// GetUGroupLogAnalysis 获取用户组日志分析
func GetUGroupLogAnalysis(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	if logAnalysis, ok := request.GetModel().(*analysismodel.GetUGroupDataAnalysis); ok {
		var result analysismodel.LogAnalysis
		result.WarnLogAnalysis = userlogservice.GetWarnLogsAnalysisByUGroupID(logAnalysis)
		result.NormLogAnalysis = userlogservice.GetNormLogsAnalysisByUGroupID(logAnalysis)
		data, _ := json.Marshal(result)
		response.Code = code.SUCCESS
		response.Data = data
		logger.Logger.Info("get ugroup log analysis success")
	} else {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "Transform interface to GetUGroupDataAnalysis fail")
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "transform interface to GetUGroupDataAnalysis fail"
	}
}

func GetLogAnalysis(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	if logAnalysis, ok := request.GetModel().(*analysismodel.GetDataAnalysis); ok {
		var result analysismodel.LogAnalysis
		result.WarnLogAnalysis = userlogservice.GetWarnLogsAnalysis(logAnalysis)
		result.NormLogAnalysis = userlogservice.GetNormLogsAnalysis(logAnalysis)
		data, _ := json.Marshal(result)
		response.Code = code.SUCCESS
		response.Data = data
		logger.Logger.Info("get log analysis success")
	} else {
		logger.Logger.ErrorWithConn(ctx.Value("conn_id").(string), "Transform interface to GetDataAnalysis fail")
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "transform interface to GetDataAnalysis fail"
	}
}

func GetAnalysisInfos(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	var infos []*analysismodel.AnalysisInfo
	ugroupInfos := ugroupdao.GetAllUGroupNameInfos()
	// 规则组数量
	for _, ugroupInfo := range ugroupInfos {
		infos = append(infos, getUGroupInfo(ugroupInfo.ID, ugroupInfo.Name))
	}
	data, _ := json.Marshal(infos)
	response.Code = code.SUCCESS
	response.Data = data
	logger.Logger.Info("get analysis info success")

}

// GetLogsAnalysisByUser 获取所有用户的日志分析柱状图
func GetLogsAnalysisByUser(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	if logType, ok := request.GetModel().(*analysismodel.LogType); ok {
		result := userlogservice.GetLogsAnalysisByUser(logType)

		if result == nil {
			logger.Logger.Error("get user extranet logs analysis fail")
			response.Code = code.BAD_REQUEST
			response.ErrorMsg = "get user extranet logs analysis fail"
			return
		}

		data, _ := json.Marshal(result)
		response.Code = code.SUCCESS
		response.Data = data
		logger.Logger.Info("get user extranet logs analysis success")

	} else {
		logger.Logger.Error("Transform interface to LogType fail")
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "transform interface to LogType fail"
	}

}

// GetLogsAnalysisByUserAndUGroupID 获取用户组内用户的日志分析柱状图
func GetLogsAnalysisByUserAndUGroupID(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	if ugroupid, ok := request.GetModel().(*analysismodel.UGroupLogType); ok {
		result := userlogservice.GetLogsAnalysisByUserAndUGroupID(ugroupid)
		if result == nil {
			logger.Logger.Error("get ugroup user extranet logs analysis fail")
			response.Code = code.BAD_REQUEST
			response.ErrorMsg = "get ugroup user extranet logs analysis fail"
			return
		}

		data, _ := json.Marshal(result)
		response.Code = code.SUCCESS
		response.Data = data
		logger.Logger.Info("get ugroup user extranet logs analysis success")
	} else {
		logger.Logger.Error("Transform interface to UGroupLogType fail")
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "transform interface to UGroupLogType fail"
	}
}

// GetLogsAnalysisByWebsite 获取所有用户的网站分析饼图
func GetLogsAnalysisByWebsite(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	if logType, ok := request.GetModel().(*analysismodel.LogType); ok {
		result := userlogservice.GetLogsAnalysisByWebsite(logType)

		if result == nil {
			logger.Logger.Error("get user extranet website logs analysis fail")
			response.Code = code.BAD_REQUEST
			response.ErrorMsg = "get user extranet website logs analysis fail"
			return
		}

		data, _ := json.Marshal(result)
		response.Code = code.SUCCESS
		response.Data = data
		logger.Logger.Info("get user extranet website logs analysis success")
	} else {
		logger.Logger.Error("Transform interface to LogType fail")
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "transform interface to LogType fail"
	}

}

// GetLogsAnalysisByWebsiteAndUGroupID 获取用户组用户的网站分析饼图
func GetLogsAnalysisByWebsiteAndUGroupID(ctx context.Context, request *network.NetRequest, response *network.NetResponse) {
	if ugroupid, ok := request.GetModel().(*analysismodel.UGroupLogType); ok {
		result := userlogservice.GetLogsAnalysisByWebsiteAndUGroupID(ugroupid)
		if result == nil {
			logger.Logger.Error("get ugroup user extranet logs analysis fail")
			response.Code = code.BAD_REQUEST
			response.ErrorMsg = "get ugroup user extranet website logs analysis fail"
			return
		}

		data, _ := json.Marshal(result)
		response.Code = code.SUCCESS
		response.Data = data
		logger.Logger.Info("get ugroup user extranet website logs analysis success")
	} else {
		logger.Logger.Error("Transform interface to UGroupLogType fail")
		response.Code = code.BAD_REQUEST
		response.ErrorMsg = "transform interface to UGroupLogType fail"
	}
}

func getUGroupInfo(ugid int, name string) *analysismodel.AnalysisInfo {
	var info analysismodel.AnalysisInfo
	info.ID = ugid
	info.Name = name
	info.UserNum = userdao.GetUserCountByUGroupID(ugid)                // 获取用户组用户数量
	info.RuleNum = ruledao.GetUGroupRulesCount(ugid)                   // 获取用户组规则数
	info.RGroupNum = rgroupdao.GetRGroupsCount(ugid)                   // 获取用户组规则组数量
	info.WhiteListNum = whitelistdao.GetWhiteListCountByUGroupID(ugid) // 获取用户组白名单数
	if logNum := userlogservice.GetUGroupLogNumByUGroupID(ugid); logNum != nil {
		info.NormLogNum = logNum.NormLogNum
		info.WarnLogNum = logNum.WarnLogNum
	}
	return &info
}
